package com.qfedu.edu.messagecenterserver.listener;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.qfedu.edu.bo.QueueMessage;
import com.qfedu.edu.mqtt.data.MessageHeader;
import com.qfedu.edu.mqtt.data.MessagePayload;
import com.qfedu.edu.mqtt.data.MessageType;
import com.qfedu.edu.mqtt.data.MqttMessage;
import com.qfedu.edu.messagecenterserver.mqtt.observer.base.SubjectHardware;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;

/**
 * @author xiaobobo
 * @title: HardwardMessageReceiveListener
 * @projectName cd-fy-2401-third-project-parent
 * @description: 这里就是硬件消息的接受监听
 * @date 2024/10/9  17:21
 */
@Component
public class HardwareMessageReceiveListener {

    @Autowired
    private SubjectHardware subject;

    /**
     * 监控硬件的消息
     * @param data
     * @param message
     * @param channel
     */
    @RabbitListener(queues = {"emqxQueue"})
    public void receive(byte[] data, Message message, Channel channel) throws UnsupportedEncodingException {
        //这里首先将data转换成字符串
        String receiveData = new String(data, "UTF-8");
        //将这个数据弄成QueueMessage对象
        QueueMessage queueMessage = JSON.parseObject(receiveData, QueueMessage.class);
        //接下来就可以取出这个消息了....
        //这个消息是JSON格式
        String msg = queueMessage.getMsg();
        //将这个消息转换成Java对象
        //这个JSONObject对象中就包含了 消息的头部信息和载荷信息
        JSONObject jsonObject = JSON.parseObject(msg);
        //就要将信息封装成头部信息 和载荷信息了...
        MessageHeader messageHeader = wrapMessageHeader(jsonObject);
        MessagePayload messagePayload = wrapMessagePayload(jsonObject);
        if(null!=messageHeader&&null!=messagePayload){
            //那么就将上述的头部信息和载荷信息封装成硬件消息
            MqttMessage mqttMessage = new MqttMessage(messageHeader, messagePayload);
            //接下来就可以  处理心跳信号 和 消息存储
            // 消息触发机制  因为只有消息来了 才会触发 心跳的维护和 硬件信息存储
            subject.notifyHandler(mqttMessage);
        }


    }



    /**
     * 封装MessagePayload对象
     * @param jsonObject
     * @return
     */
    private MessagePayload wrapMessagePayload(JSONObject jsonObject) {
        //先申明这样一个对象
        MessagePayload messagePayload = new MessagePayload();
        //接下来就可以赋值这个对象了
        JSONObject payload = jsonObject.getJSONObject("payload");
        //接下来就是设置属性值
        messagePayload.setMessageType(MessageType.MQTT);
        messagePayload.setPayload(payload.toString());
        return messagePayload;
    }

    /**
     * 将数据封装成MessageHeader对象
     *
     * @param jsonObject
     * @return
     */
    private MessageHeader wrapMessageHeader(JSONObject jsonObject) {
        JSONObject headers = jsonObject.getJSONObject("headers");
        MessageHeader messageHeader = new MessageHeader();
        messageHeader.setMqttReceivedRetained(headers.getBoolean("mqtt_receivedRetained"));
        messageHeader.setMqttId(headers.getInteger("mqtt_id"));
        messageHeader.setTimestamp(headers.getLong("timestamp"));
        messageHeader.setMqttDuplicate(headers.getBoolean("mqtt_duplicate"));
        messageHeader.setMqttReceivedQos(headers.getInteger("mqtt_receivedQos"));
        messageHeader.setMqttReceivedTopic(headers.getString("mqtt_receivedTopic"));
        messageHeader.setId(headers.getString("id"));
        return messageHeader;
    }

}
